/**
 * Copyright (c) 2023 myons Inc. All rights reserved.
 */
package cn.zmwh.im.server.config;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.zmwh.im.server.constant.Constants;
import cn.zmwh.im.server.mq.dto.LoginInfo;
import cn.zmwh.im.server.utils.AuthenticationUtil;
import cn.zmwh.im.server.utils.HttpUtil;
import cn.zmwh.im.server.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @describe: 平台过滤去 、
 * @author: dmzmwh 、
 * @time: 2023-04-10 18:11 、
 */
@Slf4j
public class ImServerGlobalFilter extends OncePerRequestFilter {

    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String TOKEN_HEADER = "Authorization";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String origin = request.getHeader("origin");
        response.setHeader("Access-Control-Allow-Origin", origin);
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        String method = request.getMethod();
        if ("OPTIONS".equals(method)) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        String authHeader = request.getHeader(TOKEN_HEADER);
        if (StrUtil.isBlank(authHeader)) {
            AuthenticationUtil.responseWriter(response);
            return;
        }
        String authToken = authHeader.replace(TOKEN_PREFIX, "");
        LoginInfo infoFromToken = JwtUtil.getInfoFromToken(authToken);
        Boolean effectivity = infoFromToken.getEffectivity();
        if (!effectivity) {
            AuthenticationUtil.responseWriter(response, 401, "用户token已过期");
            return;
        }
        Claims claims = infoFromToken.getClaims();
        Long uid = claims.get(Constants.UID, Long.class);
        if (uid == null) {
            AuthenticationUtil.responseWriter(response, 401, "用户token已过期");
            return;
        }
        String terminal = claims.get(Constants.TERMINAL, String.class);
        MutableHttpServletRequest requestWrapper = new MutableHttpServletRequest(request);
        requestWrapper.putHeader(Constants.UID, uid + "");
        requestWrapper.putHeader(Constants.TERMINAL, terminal);
        String contentType = request.getContentType();

        if ("POST".equals(method) && StrUtil.isNotBlank(contentType) && contentType.contains("application/json")) {
            String bodyStr = HttpUtil.getPostData(request);
            if (StrUtil.isBlank(bodyStr) || JSONUtil.isTypeJSONObject(bodyStr)) {
                JSONObject entries = null;
                if (StrUtil.isBlank(bodyStr)) {
                    entries = new JSONObject();
                } else {
                    entries = JSONUtil.parseObj(bodyStr);
                }
                entries.putOpt(Constants.UID, uid);
                entries.putOpt(Constants.TERMINAL, terminal);
                bodyStr = JSONUtil.toJsonStr(entries);
            }
            requestWrapper.setBodyJsonStr(bodyStr);
        }
        if ("GET".equals(method) || ("POST".equals(method) && StrUtil.isNotBlank(contentType) && contentType.contains("multipart/form-data"))) {
            requestWrapper.addParameter(Constants.UID, uid);
            requestWrapper.addParameter(Constants.TERMINAL, terminal);
        }
        filterChain.doFilter(requestWrapper, response);
    }
}
